package com.gitee.fsadmin.service.sys.impl;

import com.gitee.fsadmin.common.user.User;
import com.gitee.fsadmin.common.util.CopyUtil;
import com.gitee.fsadmin.dao.entity.SysUser;
import com.gitee.fsadmin.service.sys.SysUserService;
import com.gitee.fsadmin.service.sys.UserCacheService;
import com.gitee.fsadmin.service.sys.dto.SysUserDTO;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author 六如
 */
@Component
@Condition(onProperty = "${user.cache.type:local}=local")
public class LocalUserCacheServiceImpl implements UserCacheService {

    @Inject
    private SysUserService sysUserService;

    @Init
    public void init() {
        List<SysUser> sysUsers = sysUserService.listAll();
        List<SysUserDTO> sysUserDTOS = CopyUtil.copyList(sysUsers, SysUserDTO::new);
        for (SysUserDTO sysUserDTO : sysUserDTOS) {
            configCache.put(sysUserDTO.getUserId(), Optional.of(sysUserDTO));
        }
    }

    // key: configKey, value: configValue
    private final LoadingCache<Long, Optional<User>> configCache = CacheBuilder.newBuilder()
            .expireAfterAccess(30, TimeUnit.MINUTES)
            .build(new CacheLoader<Long, Optional<User>>() {
                @Override
                public Optional<User> load(Long key) throws Exception {
                    return Optional.ofNullable(loadFromDb(key));
                }
            });

    @Override
    public Optional<User> getUser(Long userId) {
        return configCache.getUnchecked(userId);
    }

    private User loadFromDb(Long userId) {
        SysUser sysUser = sysUserService.getById(userId);
        return CopyUtil.copyBean(sysUser, SysUserDTO::new);
    }


}
